package com.cskaoyan.javase._1extends._2conversion;

/**
 * 为什么父类引用指向子类对象是可行的? 子类"is-a"父类
 * 引用数据类型的类型转换,分析,思考以下两个问题:
 * 1.何为引用数据类型的类型转换呢？到底转换的是什么?
 *      引用数据类型变量 = 引用 + 对象
 *      引用和对象都有数据类型,但是引用数据类型的类型转换,只能转换引用的数据类型
 *
 * 引用数据类型的类型转换,也分成两种情况:
 *      1.自动类型转换,由编译器自动完成引用的类型转换,程序员无需写任何额外代码
 *      2.强制类型转换,由程序员使用特殊语法来强制完成类型转换,如果不写特殊语法,就会编译报错
 *          语法:
 *              强转后的数据类型 引用名 = (强转后的数据类型)被强制的引用;
 *
 * 2.引用数据类型的自动类型转换
 *      发生的条件是什么?
 *      父类引用指向子类对象,就是一种自动类型转换
 *      转换的是引用的数据类型: 子类引用 --> 父类引用
 *
 *      简称: 从继承的方向上来说(类比于族谱),父类在上,子类在下
 *            子类引用 --> 父类引用
 *            方向上是向上的
 *            所以引用数据类型的自动类型转换,简称为"向上转型"
 *
 * 3.引用数据类型的强制类型转换
 *      向上转型之所以是自动的,原因是子类"is-a"父类,子类本身就可以当成父类使用
 *      但是反之就不成立了
 *      发生,通过编译的条件是什么呢?
 *      父类引用 --> 子类引用
 *      这个过程相当于把父类对象,当成子类去使用,这基本上是不可能的
 *      这个过程基本上是注定失败的,是很危险的
 *      所以这个过程就是需要程序员自己手动完成的
 *
 *      引用数据类型的强制类型转换会碰到的问题:
 *      将父类当成子类去使用,这几乎一定会失败
 *      一旦失败,程序就会报错终止
 *      抛出异常: ClassCastException 类型转换异常
 *      所以引用数据类型的强制类型转换是很危险的
 *      在进行转换之前,需要考虑成功的条件
 *      (多态的时候再讲)
 *
 *      简称: 从继承的方向上来说(类比于族谱),父类在上,子类在下
 *      强转的方向是 从父类 --> 子类
 *      方向是向下的
 *      简称为"向下转型"
 *
 *
 *
 * @since 17:12
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        // 子类引用指向子类对象
        Son s = new Son();
        // 父类引用指向子类对象,那么子类引用赋值给父类引用也是可以的
        // 这个过程中,引用的类型,从子类 --> 父类,发生了引用数据类型的类型转换
        // 这个过程没有写任何额外代码,编译器自动完成,是引用数据类型的自动类型转换
        Father fs = s;
        // 以上代码二合一
        Father fs2 = new Son();
        Father fs3 = new LittleSon();

        System.out.println("------------------");
        // 这里是把Father对象,当成子类LittleSon去使用,必然是要失败的
        LittleSon s2 = (LittleSon) new Father();
    }
}

class Father {
}

class Son extends Father {
}
class LittleSon extends Father{

}